using System;
using System.Collections.Generic;
using FrameOperateSync;

namespace Pvp
{
    public partial class PvpEntry : IPvpGame
    {
        /// <summary>
        /// 游戏输入
        /// </summary>
        private Dictionary<int, InputData> unitInputDataMap = new Dictionary<int, InputData>(30);
        /// <summary>
        /// 所有角色数据
        /// </summary>
        private Dictionary<int, FightUnitEntity> unitEntityMap = new Dictionary<int, FightUnitEntity>(3);

        private PvpEntry.SkillX _skill;
        private PvpEntry.InputX _input;
        private PvpEntry.MoveX _move;
        private PvpEntry.DamageX _damage;
        private PvpEntry.HealthX _health;
        private PvpEntry.PreviousViewX _previousView;
        private PvpEntry.ViewX _view;
        private PvpEntry.BuffX _buff;
        private PvpEntry.StageX _stage;
        private bool _isLogicOnly;

        public PvpEntry(bool isLogicOnly)
        {
            _isLogicOnly = isLogicOnly;
            _skill = new SkillX(this);
            _input = new InputX(this);
            _move = new MoveX(this);
            _damage = new DamageX(this);
            _health = new HealthX(this);
            _previousView = new PreviousViewX(this);
            _view = new ViewX(this);
            _buff = new BuffX(this);
            _stage = new StageX();
        }
        public void OnPlayerJoin(int playerId)
        {
            if(!unitEntityMap.ContainsKey(playerId))
            {
                unitInputDataMap.Add(playerId, new InputData());
                unitEntityMap.Add(playerId, new FightUnitEntity());
            }
        }

        public void OnPlayerLeave(int playerId)
        {
        }

        public void OnGameDispose()
        {
        }

        public void OnGameStart()
        {
        }

        /// <summary>
        /// 核心逻辑：每一帧都运行以下循环
        /// 
        /// 收集所有输入 =》 解析输入（更改游戏对象状态数据） =》 状态数据驱动游戏逻辑（移动，技能，伤害，buff） =》 游戏逻辑反过来影响游戏数据 =》 根据游戏数据来做表现  
        /// </summary>
        /// <param name="frameIndex"></param>
        public void OnGameUpdate(int frameIndex)
        {
            //解析输入
            _input.ProcessInput();
            //预表现
            _previousView.ProcessSkill();
            //移动
            _move.ProcessMove();
            //技能
            _skill.ProcessSkill();
            //buff
            _buff.ProcessBuff();
            //伤害
            _damage.ProcessDamage();
            //血量
            _health.ProcessHealth();
            //表现
            _view.ProcessView();
            
            //输入清空
            foreach (var kvp in unitInputDataMap)
            {
                kvp.Value.curFrameOp = OperateType.none;
                kvp.Value.opData = null;
            }
        }

        public void HandleInput(int entityId, bool localFlag, OperateType opType, IRenderData inputData)
        {
            if (_isLogicOnly && localFlag)
                return;
            if (unitInputDataMap.TryGetValue(entityId, out var x))
            {
                x.curFrameOp = opType;
                x.opData = inputData;
                return;
            }

            throw new Exception("111");
        }
    }
}